/* 
 * File:   Graph.h
 * Author: RaF
 *
 * Created on 22 novembre 2012, 10.56
 */


#ifndef GRAPH_H
#define	GRAPH_H
#include<vector>
#include<list>
#include "Vertex.hpp"
#include "Edge.hpp"

template <typename I> class Graph {
public:
    //Metodi iteratore
    /**
     * Consente di ottenere l'insieme dei vertici del grafo
     * @return vertici del grafo
     */
    virtual std::vector<Vertex<I>*>* getVertices() = 0;
    /**
     * Consente di ottenere l'insieme degli archi del grafo
     * @return archi del grafo
     */
    virtual std::vector<Edge<I>*>* getEdges() = 0;
    /**
     * Ottiene gli archi adiacenti ad un vertice
     * @param v vertice su cui ottenere gli archi adiacenti
     * @return lista degli archi adiacenti
     */
    virtual std::list<Edge<I>*>* getAdjacentsEdges(Vertex<I>* v) = 0;
    //Metodi di accesso
    /**
     * Ottiene i due vertici di un arco
     * @param e arco da cui estrarre i vertici
     * @return vettore contenente i due vertici estremi di un arco
     */
    virtual std::vector<Vertex<I>*>* getEndVertices(Edge<I>* e) = 0;
    /**
     * Ottiene il vertice opposto ad un vertice presente su un arco specificato
     * @param v vertice di cui trovare l'opposto
     * @param e arco su cui cercare
     * @return restituisce il riferimento al vertice opposto.
     */
    virtual Vertex<I>* getOpposite(Vertex<I>* v, Edge<I>* e) = 0;
    /**
     * Verifica se due vertici sono adiacenti
     * @param v primo vertice
     * @param w secondo vertice
     * @return il valore booleano true in caso di adiacenza, false altrimenti.
     */
    virtual bool areAdjacent(Vertex<I>* v, Vertex<I>* w) = 0;
    /**
     * Inserisce un vertice nel grafo
     * @param info informazione da associare al vertice
     */
    virtual void insertVertex(I info) = 0;
    /**
     * Inserisce un arco nel grafo
     * @param v vertice di partenza dell'arco
     * @param w vertice di arrivo dell'arco
     * @param edgeWeight peso da associare all'arco
     */
    virtual void insertEdge(Vertex<I>* v, Vertex<I>* w, int edgeWeight) = 0;
    /**
     * Rimuove un vertice dal grafo e tutti gli archi ad esso adiacenti
     * @param v vertice da eliminare
     */
    virtual void removeVertex(Vertex<I>* v) = 0;
    /**
     * Rimuove un arco dal grafo.
     * @param e arco da rimuovere
     */
    virtual void removeEdge(Edge<I>* e) = 0;

    /**
     * Esegue la visita di profondità del grafo
     * @param doAction riferimento alla funzione da eseguire su ogni vertice visitato del grafo.
     * In caso non si voglia eseguire nessuna azione usare il valore NULL.
     * @return mappa chiave/valore delle relazioni di parentela negli alberi dei vertici visitati.
 * La chiave corrisponde al vertice figlio, mentre il valore al vertice padre.
     */
    virtual std::map<Vertex<I>*, Vertex<I>*>* VisitByDFS(void (*doAction)(Vertex<I>* v)) = 0;
};

#endif	/* GRAPH_H */

